package pogvue.gui.popups;

import pogvue.gui.AlignViewport;
import pogvue.gui.Controller;
import pogvue.gui.menus.JalActionEvent;
import pogvue.gui.menus.JalActionListener;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * This is the base of the Popup dialog hierarchy. 
 */
public class Popup extends JDialog implements JalActionListener {
  final JPanel parent;

  final AlignViewport av;
  Controller controller;

  private final JPanel doingPane;
  private final JPanel applyPane;

  final JButton apply;
  final JButton close;

  final PopupStatusLabel status;

  final GridBagLayout gb;
  final GridBagConstraints gbc;

  final PopupActionListener pal;
  private final BasicWindowListener bwl;


  private JalPopupAction applyAction = null;

  /**
   * Sets basic layout properties, sets the layout manager, and creates the
   * standard buttons (close and apply) and labels (status), and shows it.
   * @param parent The parent frame of this popup.
   * @param title  The title for this popup
	 * @param av
	 * @param c
   */
  public Popup(JPanel parent, AlignViewport av, Controller c,String title) {
  //  super(parent,title,false);
    this.parent = parent;
    this.av = av;
    this.controller = c;

    doingPane = new JPanel();
    applyPane = new JPanel();
    apply     = new JButton("Apply");
    close     = new JButton("Cancel");

    getContentPane().setLayout(new BorderLayout());
    getContentPane().add("Center",doingPane);
    getContentPane().add("South",applyPane);

    gb  = new GridBagLayout();
    gbc = new GridBagConstraints();

    gbc.fill = GridBagConstraints.NONE;
    gbc.insets = new Insets(10,10,10,10);
    applyPane.setLayout(gb);
    
    add(apply,gb,gbc,0,0,1,1,applyPane);
    add(close,gb,gbc,1,0,1,1,applyPane);

    doingPane.setLayout(gb);

    status = new PopupStatusLabel("Status:",Label.LEFT);
    status.setHorizontalAlignment(Label.LEFT);

    pal = new PopupActionListener(this);
    bwl = new BasicWindowListener(this);
  }

  void setApplyAction(JalPopupAction jpa) {
    if (apply != null) {
      if (applyAction != null) {
        if (av != null && av.getCommandLog() != null) {
          av.getCommandLog().remove(applyAction);
        }
        applyAction.removeListener(this);
        apply.removeActionListener(applyAction);
        applyAction.removeListener(status);
      }
      apply.addActionListener(jpa);
      if (av != null && av.getCommandLog() != null) {
        av.getCommandLog().add(jpa);
      }
      this.applyAction = jpa;
      applyAction.addListener(this);
      if (contains(status)) {
        applyAction.addListener(status);
      }
    }
  }

  private boolean contains(Component comp) {
    Component [] comps = getComponents();
		for (Component comp1 : comps) {
			if (comp1 == comp) {
				return true;
			}
		}
		return false;
  }

  public void handleJalAction(JalActionEvent evt) {

    if (evt.getActionType() == JalActionEvent.DONE) {
      this.setVisible(false);
      this.dispose();
    }
  }

  public void addBasic() {
      applyPane.add(apply,gbc);
      applyPane.add(close,gbc);
      doingPane.add(status,gbc);
    pack();
    validate();
    setVisible(true);
  }

  final class PopupActionListener implements ActionListener {
    final Popup p;
    public PopupActionListener(Popup p) {
      this.p = p;
      apply.addActionListener(this);
      close.addActionListener(this);
    }
    public void actionPerformed(ActionEvent evt) {
      if (evt.getSource() == apply) {
        applyAction(evt);
      } else if (evt.getSource() == close) {
        closeAction(evt);
      } else {
        otherAction(evt);
      }
    }
  }

  /**
   * The method called when the apply button is pressed.
	 * @param evt
	 */
	void applyAction(ActionEvent evt) {
    if (applyAction == null) {
      System.out.println("Default Popup applyAction - no functionality. You should do a setApplyAction\n");
    }
  }

  void closeAction(ActionEvent evt) {
    this.setVisible(false);
    this.dispose();
  }

  void otherAction(ActionEvent evt) {
    System.out.println("Default Popup otherAction - no functionality - override in your class\n");
  }

  final class BasicWindowListener extends WindowAdapter {
    final Popup p;
    public BasicWindowListener(Popup p) {
      this.p = p;
      p.addWindowListener(this);
    }
    public void windowClosing(WindowEvent evt) {
      System.out.println("Calling windowClosing");
      status.setText("Closing window...");
      status.validate();
      p.setVisible(false);
      p.dispose();
    }
  }

  /**
   * add a component to the popup, with specified constraints.
   * @param c   The component to add
   * @param gbl The layout manager
   * @param gbc The constraints object (this is modified within the method
   * @param x   Becomes gbc.gridx
   * @param y   Becomes gbc.gridy
   * @param w   Becomes gbc.gridwidth
   * @param h   Becomes gbc.gridheight
	 * @param p
   */
	private void add(Component c,GridBagLayout gbl, GridBagConstraints gbc,
                  int x, int y, int w, int h,JPanel p) {
    gbc.gridx = x;
    gbc.gridy = y;
    gbc.gridwidth = w;
    gbc.gridheight = h;
    gbl.setConstraints(c,gbc);
    p.add(c);
  }
  void add(Component c,GridBagLayout gbl, GridBagConstraints gbc,
                  int x, int y, int w, int h) {
      add(c,gb,gbc,x,y,w,h,doingPane);
  }

  public void dispose() {
    super.dispose();
    System.out.println("dispose called on " + this);
  }

  public static void main(String[] args) {
    JPanel        frame = new JPanel();
    Controller    c     = new Controller();
    Popup         popup = new Popup(frame,null,c,"Test popup");

    frame.setVisible(true);

    popup.setSize(200,200);

    popup.setVisible(true);
  }
}











